#ifndef SC_CONFIG_H_INCLUDED
#define SC_CONFIG_H_INCLUDED

#include "libxml/parser.h"
#include "libxml/xpath.h"

#include <string>
#include <list>
#include <map>

namespace sc {

/**
* @class Config
*
* This class represent the grammar of the Setup. It is based on Relax NG document.
*/
class Config
{
public:
    /**
    * Attribute
    */
	struct Attribute;
	typedef std::list<Attribute>  TListAttribut;

    struct Attribute
    {
        enum Mask { INT, DOUBLE, STRING, CHOICE };
		typedef std::list<std::string> TChoices;

        Mask        mask;
        std::string sName;
		TChoices    lstChoice;
    };


    /**
    * Element
    */
	struct Element;
    typedef std::map<std::string,Element>    TMapElement;
    typedef std::list<TMapElement::iterator> TListChild;

    struct Element
    {
        enum Type { UNIQUE, OPTION, MULTIPLE };

        std::string   sName;
        Type          type;
        TListChild    children;
        TListAttribut attributes;
    };

public:
    Config(void);
    ~Config(void);

protected:
    std::string        m_sFilename;  //!< File name of the RNG file

    xmlDocPtr          m_rngDoc;     //!< xml document of the RNG file
    xmlXPathContextPtr m_xpathCtx;   //!< XPath context

    TMapElement        m_mapElement; //!< Map of available Element

public:
    int LoadRng(const std::string& sFile);

    int GetRoot(std::string& sRoot) const;
    const TMapElement& GetElements(void) const { return m_mapElement; }

    void Clear(void);

    static bool IsRngValid(const std::string& sFileRNG);

protected:
    int GetChildren(TMapElement::iterator iterRoot);
    int GetAttribute(Element& rElement, xmlNodePtr node);
	int GetAttributeData(Attribute& rAttribute, xmlNodePtr node);
	int GetAttributeChoice(Attribute& rAttribute, xmlNodePtr node);

	int GetChildren(TMapElement::iterator iterRoot, xmlNodePtr node, Element::Type type);
	int GetElement(TMapElement::iterator parent, xmlNodePtr node, Element::Type type);
};

};

#endif // SC_CONFIG_H_INCLUDED
